import time
from gate_api import SpotApi, FuturesApi, Configuration, ApiClient
import logging
import json
import threading
import websocket

class GatePriceMonitor:
    def __init__(self):
        # 价格数据存储
        self.futures_price = {}
        self.spot_price = {}
        
        # websocket连接
        self.futures_ws = None
        self.spot_ws = None
        
        # 初始化日志
        logging.basicConfig(
            level=logging.INFO,
            format='%(asctime)s - %(levelname)s - %(message)s'
        )
        self.logger = logging.getLogger(__name__)

    def on_futures_message(self, ws, message):
        """处理合约websocket消息"""
        try:
            data = json.loads(message)
            if 'event' in data and data['event'] == 'update':
                if data['channel'] == 'futures.tickers':
                    tickers = data['result']
                    for ticker in tickers:
                        symbol = ticker['contract']
                        self.futures_price[symbol] = {
                            'price': float(ticker['last']),
                            'funding_rate': float(ticker['funding_rate'])
                        }
        except Exception as e:
            self.logger.error(f"处理合约消息错误: {str(e)}")

    def on_spot_message(self, ws, message):
        """处理现货websocket消息"""
        try:
            data = json.loads(message)
            if 'event' in data and data['event'] == 'update':
                if data['channel'] == 'spot.tickers':
                    ticker = data['result']
                    symbol = ticker['currency_pair']
                    self.spot_price[symbol] = {
                        'price': float(ticker['last'])
                    }
        except Exception as e:
            self.logger.error(f"处理现货消息错误: {str(e)}")

    def start_websockets(self, symbols: list):
        """启动websocket连接"""
        def futures_ws_thread():
            while True:
                try:
                    self.futures_ws = websocket.WebSocketApp(
                        "wss://fx-ws.gateio.ws/v4/ws/usdt",
                        on_message=self.on_futures_message
                    )
                    self.futures_ws.run_forever()
                except Exception as e:
                    self.logger.error(f"合约Websocket错误: {str(e)}")
                    time.sleep(5)

        def spot_ws_thread():
            while True:
                try:
                    self.spot_ws = websocket.WebSocketApp(
                        "wss://api.gateio.ws/ws/v4/",
                        on_message=self.on_spot_message
                    )
                    self.spot_ws.run_forever()
                except Exception as e:
                    self.logger.error(f"现货Websocket错误: {str(e)}")
                    time.sleep(5)

        # 启动websocket线程
        threading.Thread(target=futures_ws_thread, daemon=True).start()
        threading.Thread(target=spot_ws_thread, daemon=True).start()
        
        # 等待连接建立
        time.sleep(3)

        # 订阅合约行情
        for symbol in symbols:
            self.futures_ws.send(json.dumps({
                "time": int(time.time()),
                "channel": "futures.tickers",
                "event": "subscribe",
                "payload": [f"{symbol}_USDT"]
            }))

        # 订阅现货行情
        for symbol in symbols:
            self.spot_ws.send(json.dumps({
                "time": int(time.time()),
                "channel": "spot.tickers",
                "event": "subscribe",
                "payload": [f"{symbol}_USDT"]
            }))

    def print_price_diff(self):
        """打印价格差异"""
        print("\n" + "="*80)
        print(f"时间: {time.strftime('%Y-%m-%d %H:%M:%S')}")
        print("-"*80)
        print(f"{'交易对':<15} {'合约价格':<15} {'现货价格':<15} {'价差(%)':<15} {'资金费率(%)':<15}")
        print("-"*80)
        
        for symbol in self.futures_price:
            spot_symbol = symbol.replace('_USDT', '') + '_USDT'
            if spot_symbol in self.spot_price:
                futures_data = self.futures_price[symbol]
                spot_data = self.spot_price[spot_symbol]
                
                futures_price = futures_data['price']
                spot_price = spot_data['price']
                price_diff = (futures_price - spot_price) / spot_price * 100
                funding_rate = futures_data['funding_rate'] * 100
                
                print(f"{symbol:<15} {futures_price:<15.8f} {spot_price:<15.8f} "
                      f"{price_diff:>15.4f} {funding_rate:>15.4f}")
        print("="*80 + "\n")

    def run(self, symbols: list):
        """运行监控"""
        self.start_websockets(symbols)
        
        while True:
            try:
                self.print_price_diff()
                time.sleep(3)
            except KeyboardInterrupt:
                print("\n正在退出程序...")
                break
            except Exception as e:
                self.logger.error(f"运行错误: {str(e)}")
                time.sleep(3)

def main():
    # 要监控的交易对
    symbols = ['BTC', 'ETH', 'WOLF']  # 可以添加更多交易对
    
    # 创建监控实例
    monitor = GatePriceMonitor()
    
    # 运行监控
    monitor.run(symbols)

if __name__ == "__main__":
    main() 